package org.cboard.controller;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.cboard.dao.BoardDao;
import org.cboard.dao.CategoryDao;
import org.cboard.dao.DatasetDao;
import org.cboard.dao.DatasourceDao;
import org.cboard.dao.JobDao;
import org.cboard.dao.WidgetDao;
import org.cboard.dao.WidgetLinkDao;
import org.cboard.dataprovider.DataProvider;
import org.cboard.dataprovider.DataProviderManager;
import org.cboard.dataprovider.DataProviderViewManager;
import org.cboard.dataprovider.config.AggConfig;
import org.cboard.dataprovider.config.LinkJsonConfig;
import org.cboard.dataprovider.result.AggregateResult;
import org.cboard.dto.DashboardMenu;
import org.cboard.dto.DataProviderResult;
import org.cboard.dto.ViewAggConfig;
import org.cboard.dto.ViewDashboardBoard;
import org.cboard.dto.ViewDashboardDataset;
import org.cboard.dto.ViewDashboardDatasource;
import org.cboard.dto.ViewDashboardJob;
import org.cboard.dto.ViewDashboardWidget;
import org.cboard.dto.WidgetLinkParam;
import org.cboard.dto.WidgetLinkPassive;
import org.cboard.pojo.DashboardBoard;
import org.cboard.pojo.DashboardBoardParam;
import org.cboard.pojo.DashboardCategory;
import org.cboard.pojo.DashboardDataset;
import org.cboard.pojo.DashboardDatasource;
import org.cboard.pojo.DashboardWidget;
import org.cboard.pojo.DashboardWidgetLink;
import org.cboard.query.DyParamHandlerManager;
import org.cboard.query.JsonParseUtils;
import org.cboard.query.QueryConstant;
import org.cboard.query.QueryParameter;
import org.cboard.security.token.TokenUtils;
import org.cboard.security.utils.DateUtils;
import org.cboard.security.utils.PropertiesLoader;
import org.cboard.services.AuthenticationService;
import org.cboard.services.BoardService;
import org.cboard.services.CategoryService;
import org.cboard.services.DataProviderService;
import org.cboard.services.DatasetService;
import org.cboard.services.DatasourceService;
import org.cboard.services.MenuService;
import org.cboard.services.ServiceStatus;
import org.cboard.services.ServiceStatusWithData;
import org.cboard.services.WidgetService;
import org.cboard.services.job.JobService;
import org.cboard.services.persist.excel.XlsProcessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baidu.ueditor.ActionEnter;
import com.google.common.base.Functions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Created by yfyuan on 2016/8/9.
 */
@RestController
@RequestMapping({"/dashboard", "/public/dashboard"})
public class DashboardController {

    private static PropertiesLoader loader = new PropertiesLoader("ui_config.properties");

    @Autowired
    private BoardDao boardDao;

    @Autowired
    private DatasourceDao datasourceDao;

    @Autowired
    private DataProviderService dataProviderService;

    @Autowired
    private DatasourceService datasourceService;

    @Autowired
    private WidgetService widgetService;

    @Autowired
    private WidgetDao widgetDao;
    
    @Autowired
    private WidgetLinkDao widgetLinkDao;

    @Autowired
    private BoardService boardService;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AuthenticationService authenticationService;

    @Autowired
    private DatasetDao datasetDao;

    @Autowired
    private MenuService menuService;
    
    @Autowired
    private DatasetService datasetService;

    @Autowired
    private JobService jobService;

    @Autowired
    private JobDao jobDao;

    @Autowired
    private XlsProcessService xlsProcessService;

    @RequestMapping(value = "/test")
    public ServiceStatus test(@RequestParam(name = "datasource", required = false) String datasource, @RequestParam(name = "query", required = false) String query) {
        JSONObject queryO = JSONObject.parseObject(query);
        JSONObject datasourceO = JSONObject.parseObject(datasource);
        if(queryO==null){
        	return dataProviderService.test(datasourceO,null);
        }else  return dataProviderService.test(datasourceO, Maps.transformValues(queryO, Functions.toStringFunction()));
    }

    @RequestMapping(value = "/getDatasourceList")
    public List<ViewDashboardDatasource> getDatasourceList() {
        String userid = authenticationService.getCurrentUser().getUserId();
        return datasourceService.getViewDatasourceList(() -> datasourceDao.getDatasourceList(userid));
    }

    @RequestMapping(value = "/getProviderList")
    public Set<String> getProviderList() {
        return DataProviderManager.getProviderList();
    }

    @RequestMapping(value = "/getConfigView")
    public String getConfigView(@RequestParam(name = "type") String type) {
        return DataProviderViewManager.getQueryView(type);
    }

    @RequestMapping(value = "/getDatasourceView")
    public String getDatasourceView(@RequestParam(name = "type") String type) {
        return DataProviderViewManager.getDatasourceView(type);
    }

    @RequestMapping(value = "/saveNewDatasource")
    public ServiceStatus saveNewDatasource(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return datasourceService.save(userid, json);
    }

    @RequestMapping(value = "/updateDatasource")
    public ServiceStatus updateDatasource(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return datasourceService.update(userid, json);
    }

    @RequestMapping(value = "/deleteDatasource")
    public ServiceStatus deleteDatasource(@RequestParam(name = "id") Long id) {

        String userid = authenticationService.getCurrentUser().getUserId();
        //删除数据源时，需要先检查此数据源是否有任何的数据集依赖，如果有，返回提示不准删除。
        ServiceStatus serviceStatus = datasetService.checkDataSourceIsStillDependent(userid, id);
        if (!StringUtils.isEmpty(serviceStatus.getMsg())) {
            return serviceStatus;
        }
        return datasourceService.delete(userid, id);
    }

    @RequestMapping(value = "/saveNewWidget")
    public ServiceStatus saveNewWidget(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return widgetService.save(userid, json);
    }

    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/getAllWidgetList")
    public List<ViewDashboardWidget> getAllWidgetList() {
        List<DashboardWidget> list = widgetDao.getAllWidgetList();
        return Lists.transform(list, ViewDashboardWidget.TO);
    }

    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/getWidgetList")
    public List<ViewDashboardWidget> getWidgetList() {

        String userid = authenticationService.getCurrentUser().getUserId();
        List<DashboardWidget> list = widgetDao.getWidgetList(userid);
        return Lists.transform(list, ViewDashboardWidget.TO);
    }

    @RequestMapping(value = "/updateWidget")
    public ServiceStatus updateWidget(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return widgetService.update(userid, json);
    }

    @RequestMapping(value = "/deleteWidget")
    public ServiceStatus deleteWidget(@RequestParam(name = "id") Long id) {
        String userid = authenticationService.getCurrentUser().getUserId();
        //检查对应的图表是否还存在看板的依赖
        ServiceStatus serviceStatus = boardService.checkIsWidgetStillDependent(userid, id);
        if (!StringUtils.isEmpty(serviceStatus.getMsg())) {
            return serviceStatus;
        }
        return widgetService.delete(userid, id);
    }

    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/getBoardList")
    public List<ViewDashboardBoard> getBoardList() {

        String userid = authenticationService.getCurrentUser().getUserId();
        List<DashboardBoard> list = boardService.getBoardList(userid);
        return Lists.transform(list, ViewDashboardBoard.TO);
    }

    @RequestMapping(value = "/saveNewBoard")
    public ServiceStatusWithData<?> saveNewBoard(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return boardService.save(userid, json);
    }

    @RequestMapping(value = "/updateBoard")
    public ServiceStatusWithData<?> updateBoard(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return boardService.update(userid, json);
    }

    @RequestMapping(value = "/deleteBoard")
    public ServiceStatus deleteBoard(@RequestParam(name = "id") Long id) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return boardService.delete(userid, id);
    }

    @RequestMapping(value = "/getBoardData")
    public ViewDashboardBoard getBoardData(@RequestParam(name = "id", required = false) Long id, @RequestParam(name = "token", required = false) String token) throws Exception {
        Long tempId = 0L;
        String theme = "";
        ViewDashboardBoard view;
        if (StringUtils.isNotEmpty(token)) {
            JSONObject obj = TokenUtils.parseToken(token);
            tempId =   obj.getLong("boardId");
            theme = obj.getString("theme");
        }else if (id != null && id > 0) {
            tempId = id;
        } 
        view = boardService.getBoardData(tempId);
        view.settheme(theme);
        
        Map<Long,List<WidgetLinkPassive>> map=getWidgetRelationMap(tempId);
        
       
        JSONArray rows = (JSONArray) view.getLayout().get("rows");
        for (Object row : rows) {
            JSONArray widgets = ((JSONObject) row).getJSONArray("widgets");
            if (widgets == null) {
                continue;
            }
            for (Object widget : widgets) {
            	JSONObject vw = ((JSONObject) widget).getJSONObject("widget");
                Long widgetId = vw.getLong("id");
                if(map.containsKey(widgetId)){
                	//有关联
                	List<WidgetLinkPassive> passiveList= map.get(widgetId);
                	if(passiveList!=null && passiveList.size()>0){
                    	JSONObject vwc = vw.getJSONObject("data").getJSONObject("config");
                        vwc.put("bylinkage", passiveList);
                	}
                }
            }
        }
        return view;
    }

    @RequestMapping(value = "/saveNewCategory")
    public ServiceStatus saveNewCategory(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return categoryService.save(userid, json);
    }

    @RequestMapping(value = "/getCategoryList")
    public List<DashboardCategory> getCategoryList() {
        return categoryDao.getCategoryList();
    }
    

    @RequestMapping(value = "/getDefauteUrl")
    public JSONObject getDefauteUrl() {
	JSONObject json = new JSONObject();
	json.put("categoryName", "");
	json.put("boardId", "");
	json.put("menuCode", "");
	String userid = authenticationService.getCurrentUser().getUserId();
	List<DashboardBoard> list = boardService.getBoardList(userid);
	if (list != null && list.size() > 0) {
	    json.put("boardId", list.get(0).getId());
	    String categoryName = list.get(0).getCategoryName();
	    json.put("categoryName", categoryName);
	}
	List<DashboardMenu> menu = menuService.getMenuList();
	DashboardMenu first = null;
	if (menu != null && menu.size() > 0) {
	    for (DashboardMenu m : menu) {
		if (!m.getMenuCode().equals("config") && !m.getMenuCode().equals("admin")) {
            first = m;
		    break;
		}
	    }
	}
	if (first != null) {
	    json.put("menuCode", first.getMenuCode());
	}
	return json;
    }

    @RequestMapping(value = "/getBoardCountUnderCategory")
    public int getBoardCountUnderCategory(@RequestParam(name = "id") Long id) {
        return boardDao.getBoardCountUnderCategoryId(id);
    }

    @RequestMapping(value = "/updateCategory")
    public ServiceStatus updateCategory(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        return categoryService.update(userid, json);
    }

    @RequestMapping(value = "/deleteCategory")
    public String deleteCategory(@RequestParam(name = "id") Long id) {
        return categoryService.delete(id);
    }

    @RequestMapping(value = "/getWidgetCategoryList")
    public List<String> getWidgetCategoryList() {
        return widgetDao.getCategoryList();
    }

    private String sqlParamWithCondtion(String json){
    	//解析sql 格式：
        JSONObject dataJson = JSONObject.parseObject(json);
        JSONObject tmp= dataJson.getJSONObject("data");
        JSONObject query = tmp.getJSONObject(QueryConstant.QUERY);
		   String parameters = query.getString(QueryConstant.PARAMETERS);
			if (parameters != null && parameters.length() > 10) {
				List<QueryParameter> queryParams = JsonParseUtils.parseJson(parameters, QueryParameter.class);
					for (QueryParameter queryParam : queryParams) {
						if ("sql".equals(queryParam.getDataSource())){
							Map<String, String> sqlMap = Maps.newHashMap();
							sqlMap.put(QueryConstant.SQL, queryParam.getContent());
							Long datasourceId = tmp.getLong(QueryConstant.DATASOURCE);
							DashboardDatasource datasource = datasourceDao.getDatasource(datasourceId);
							JSONObject datasourceConfig = JSONObject.parseObject(datasource.getConfig());
							Map<String, String> dataSource = Maps.transformValues(datasourceConfig,Functions.toStringFunction());
                            List ret=null;
							try {
								DataProvider dataProvider = DataProviderManager.getDataProvider(datasource.getType(),dataSource, sqlMap);
                                assert dataProvider != null;
                                String data[][] = dataProvider.getData();
                                ret= DyParamHandlerManager.getSqlParamValue(queryParam,data);
							} catch (Exception e) {
								e.printStackTrace();
							}
							queryParam.setData(ret);
						}
				}
					query.remove(QueryConstant.PARAMETERS);
					query.put(QueryConstant.PARAMETERS, queryParams);
					tmp.put(QueryConstant.QUERY, query);
					dataJson.put("data", tmp);
		}
        
			return dataJson.toJSONString();
    }
    
    @RequestMapping(value = "/saveNewDataset")
    public ServiceStatusWithData<?> saveNewDataset(@RequestParam(name = "json") String json) {

        String userid = authenticationService.getCurrentUser().getUserId();
        
        return datasetService.save(userid, sqlParamWithCondtion(json));
    }

    @RequestMapping(value = "/getAllDatasetList")
    public List<ViewDashboardDataset> getAllDatasetList() {
        List<DashboardDataset> list = datasetDao.getAllDatasetList();
        return Lists.transform(list, ViewDashboardDataset.TO);
    }

    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/getDatasetList")
    public List<ViewDashboardDataset> getDatasetList(@RequestParam(name = "userid", required = false) String userid) {
        if (StringUtils.isEmpty(userid))
            userid = authenticationService.getCurrentUser().getUserId();
        List<DashboardDataset> list = datasetDao.getDatasetList(userid);
        return Lists.transform(list, ViewDashboardDataset.TO);
    }
    @RequestMapping(value = "/updateDataset")
    public ServiceStatusWithData<?> updateDataset(@RequestParam(name = "json") String json) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return datasetService.update(userid, sqlParamWithCondtion(json));
    }

    @RequestMapping(value = "/deleteDataset")
    public ServiceStatus deleteDataset(@RequestParam(name = "id") Long id) {

        String userid = authenticationService.getCurrentUser().getUserId();
        //检查对应的数据集是否还在被图表所使用
        ServiceStatus serviceStatus = widgetService.checkDataSetIsStillDependent(userid, id);
        if (!StringUtils.isEmpty(serviceStatus.getMsg())) {
            return serviceStatus;
        }
        return datasetService.delete(userid, id);
    }

    @RequestMapping(value = "/getDatasetCategoryList")
    public List<String> getDatasetCategoryList() {
        return datasetDao.getCategoryList();
    }

    @RequestMapping(value = "/checkWidget")
    public ServiceStatus checkWidget(@RequestParam(name = "id") Long id) {
        return widgetService.checkRule(authenticationService.getCurrentUser().getUserId(), id);
    }

    @RequestMapping(value = "/checkDatasource")
    public ServiceStatus checkDatasource(@RequestParam(name = "id") Long id) {
        return datasourceService.checkDatasource(authenticationService.getCurrentUser().getUserId(), id);
    }

    @RequestMapping(value = "/getDimensionValues")
    public String[] getDimensionValues(@RequestParam(name = "datasourceId", required = false) Long datasourceId, @RequestParam(name = "query", required = false) String query, @RequestParam(name = "datasetId", required = false) Long datasetId, @RequestParam(name = "colmunName", required = true) String colmunName, @RequestParam(name = "cfg", required = false) String cfg, @RequestParam(name = "reload", required = false, defaultValue = "false") Boolean reload) {
        Map<String, String> strParams = null;
        if (query != null) {
            JSONObject queryO = JSONObject.parseObject(query);
            strParams = Maps.transformValues(queryO, Functions.toStringFunction());
        }
        AggConfig config = null;
        if (cfg != null) {
            config = ViewAggConfig.getAggConfig(JSONObject.parseObject(cfg, ViewAggConfig.class));
        }
        return dataProviderService.getDimensionValues(datasourceId, strParams, datasetId, colmunName, config, reload);
    }

    @RequestMapping(value = "/getColumns")
    public DataProviderResult getColumns(@RequestParam(name = "datasourceId", required = false) Long datasourceId,
                                         @RequestParam(name = "query", required = false) String query,
                                         @RequestParam(name = "datasetId", required = false) Long datasetId, @RequestParam(name = "reload", required = false, defaultValue = "false") Boolean reload) {
        Map<String, String> strParams = null;
        if (query != null) {
            JSONObject queryO = JSONObject.parseObject(query);
            strParams = Maps.transformValues(queryO, Functions.toStringFunction());
        }
        return dataProviderService.getColumns(datasourceId, strParams, datasetId, reload);
    }

    @RequestMapping(value = "/getAggregateData")
    public AggregateResult getAggregateData(@RequestParam(name = "datasourceId", required = false) Long datasourceId,
                                            @RequestParam(name = "query", required = false) String query,
                                            @RequestParam(name = "param", required = false) String dyParams,
                                            @RequestParam(name = "datasetId", required = false) Long datasetId,
                                            @RequestParam(name = "cfg") String cfg,
                                            @RequestParam(name = "reload", required = false, defaultValue = "false") Boolean reload) {
        Map<String, String> strParams = null;
        if (query != null) {
            JSONObject queryO = JSONObject.parseObject(query);
            strParams = Maps.transformValues(queryO, Functions.toStringFunction());
        }
        
        AggConfig config = ViewAggConfig.getAggConfig(JSONObject.parseObject(cfg, ViewAggConfig.class));
        config.setDyParams(dyParams);//动态参数
        //联动设置
        if (config.getLinkJsonConfig() != null) {
			LinkJsonConfig lj = JSONObject.parseObject(config.getLinkJsonConfig(), LinkJsonConfig.class);
			if (datasetId == null) {
				DashboardWidget dw = widgetDao.getWidget(lj.getWidgetId());
				JSONObject dataJson = JSONObject.parseObject(dw.getData());
				datasetId = dataJson.getLong("datasetId");
			}
            WidgetLinkParam ac = JSONObject.parseArray(lj.getActiveWidgetConfig(), WidgetLinkParam.class).get(0);
            DashboardWidget activeW = widgetDao.getWidget(ac.getWidgetId());

            config.putLinkParam(lj.getParams(activeW.getData(),ac));
		}

        AggregateResult result=dataProviderService.queryAggData(datasourceId, strParams, datasetId, config, reload);
        return result;
    }

    @RequestMapping(value = "/viewAggDataQuery")
    public String[] viewAggDataQuery(@RequestParam(name = "datasourceId", required = false) Long datasourceId, @RequestParam(name = "query", required = false) String query, @RequestParam(name = "datasetId", required = false) Long datasetId, @RequestParam(name = "cfg") String cfg) {
        Map<String, String> strParams = null;
        if (query != null) {
            JSONObject queryO = JSONObject.parseObject(query);
            strParams = Maps.transformValues(queryO, Functions.toStringFunction());
        }
        AggConfig config = ViewAggConfig.getAggConfig(JSONObject.parseObject(cfg, ViewAggConfig.class));
        return new String[]{dataProviderService.viewAggDataQuery(datasourceId, strParams, datasetId, config)};
    }

    @RequestMapping(value = "/dashboardWidget")
    public ViewDashboardWidget dashboardWidget(@RequestParam(name = "id") Long id) {
        DashboardWidget widget = widgetDao.getWidget(id);
        return new ViewDashboardWidget(widget);
    }

    @RequestMapping(value = "/saveJob")
    public ServiceStatus saveJob(@RequestParam(name = "json") String json) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return jobService.save(userid, json);
    }

    @RequestMapping(value = "/updateJob")
    public ServiceStatus updateJob(@RequestParam(name = "json") String json) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return jobService.update(userid, json);
    }

    @RequestMapping(value = "/getJobList")
    public List<ViewDashboardJob> getJobList() {
        String userid = authenticationService.getCurrentUser().getUserId();
        return jobDao.getJobList(userid).stream().map(ViewDashboardJob::new).collect(Collectors.toList());
    }

    @RequestMapping(value = "/deleteJob")
    public ServiceStatus deleteJob(@RequestParam(name = "id") Long id) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return jobService.delete(userid, id);
    }

    @RequestMapping(value = "/execJob")
    public ServiceStatus execJob(@RequestParam(name = "id") Long id) {
        String userid = authenticationService.getCurrentUser().getUserId();
        return jobService.exec(userid, id);
    }

    @RequestMapping(value = "/exportBoard")
    public ResponseEntity<byte[]> exportBoard(@RequestParam(name = "id") Long id) {
        String userid = authenticationService.getCurrentUser().getUserId();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "report.xls");
        return new ResponseEntity<>(boardService.exportBoard(id, userid), headers, HttpStatus.CREATED);
    }

    @RequestMapping(value = "/tableToxls")
    public ResponseEntity<byte[]> tableToxls(@RequestParam(name = "data") String data) {
        HSSFWorkbook wb = xlsProcessService.tableToxls(JSONObject.parseObject(data));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            wb.write(out);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", "table.xls");
            return new ResponseEntity<>(out.toByteArray(), headers, HttpStatus.CREATED);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(value = "/getJobStatus")
    public ViewDashboardJob getJobStatus(@RequestParam(name = "id") Long id) {
        return new ViewDashboardJob(jobDao.getJob(id));
    }

	@RequestMapping(value = "/getBoardParam")
	public DashboardBoardParam getBoardParam(@RequestParam(name = "boardId",required = false) Long boardId,@RequestParam(name = "token", required = false) String token) {

		String userid = authenticationService.getCurrentUser().getUserId();
		Long tempId = 0L;
		try {
			if (StringUtils.isNotEmpty(token)) {
				JSONObject obj = TokenUtils.parseToken(token);
				tempId =  obj.getLong("boardId");
			} else if (boardId != null && boardId > 0) {
				tempId = boardId;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return boardDao.getBoardParam(tempId, userid);
	}

    @RequestMapping(value = "/saveBoardParam")
    @Transactional
    public String saveBoardParam(@RequestParam(name = "boardId") Long boardId, @RequestParam(name = "config") String config) {
        String userid = authenticationService.getCurrentUser().getUserId();
        if (boardId == null) {
            return "";
        }
        DashboardBoardParam boardParam = new DashboardBoardParam();
        boardParam.setBoardId(boardId);
        boardParam.setUserId(userid);
        boardParam.setConfig(config);
        boardDao.deleteBoardParam(boardId, userid);
        boardDao.saveBoardParam(boardParam);
        return "1";
    }

    @ExceptionHandler
    public ServiceStatus exp(HttpServletResponse response, Exception ex) {
        response.setStatus(500);
        return new ServiceStatus(ServiceStatus.Status.Fail, ex.getMessage());
    }
	
	
	@RequestMapping(value = "/publish")
    public ServiceStatus publish(HttpServletRequest request,
                                 @RequestParam(name = "id") Long boardId,
                                 @RequestParam(name = "status") Integer status,
                                 @RequestParam(name = "theme") String theme) {

        String address=request.getScheme()+"://"+ request.getServerName()+":"+request.getServerPort()+request.getContextPath();
        long userId=Long.parseLong(authenticationService.getCurrentUser().getUserId());
        return boardService.publish(address,userId, boardId, status,theme);
    }

	
	//-------------------------联动-----------------------------------
	
	private Map<Long,List<WidgetLinkPassive>> getWidgetRelationMap(Long boardId) {
		List<Long> idList=getBoardWidgetId(boardId);
		Map<Long,List<WidgetLinkPassive>> map = Maps.newHashMap();
		if(idList!=null && !idList.isEmpty()){
			//当前图表关联的Id
			for(Long id:idList){
				List<DashboardWidgetLink> list=widgetLinkDao.getRelationWidget(id,idList);
				if(!list.isEmpty()){
					List<WidgetLinkPassive> list1=Lists.newArrayList();
					for(DashboardWidgetLink dwl:list){
						WidgetLinkPassive wlp=new WidgetLinkPassive();
						wlp.setWidgetId(dwl.getPassiveWidgetId());
						wlp.setPassiveWidgetConfig(JSONObject.parseArray(dwl.getPassiveWidgetConfig(),WidgetLinkParam.class));
						list1.add(wlp);
					}
					map.put(id, list1);
				}
			}
		}
		return map;
		
	}
	private List<Long> getBoardWidgetId(Long boardId) {
		DashboardBoard board = boardDao.getBoard(boardId);
		//整个看板上的图标ID
		List<Long> widgetList = Lists.newArrayList();
		String regularExpression = "\"widgetId\":[0-9]+";
		Pattern pattern = Pattern.compile(regularExpression);// 匹配的模式
		String dataJson = board.getLayout();
		if (!StringUtils.isEmpty(dataJson)) {
			// 使用正则表达式匹配获取对应的widget的id
			Matcher matcher = pattern.matcher(dataJson);
			while (matcher.find()) {
				// widgetKeyValue 的格式为："widgetId":28
				String widgetIdKeyValue = matcher.group(0);
				String widgetIdValue = widgetIdKeyValue.split(":")[1];
				if(!widgetList.contains(Long.parseLong(widgetIdValue))){
					widgetList.add(Long.parseLong(widgetIdValue));
				}
			}
		}
		return widgetList;
	}
	
	
	//-----------------------ueditor-------------------------------

    @RequestMapping(value = "/getUeditorConfig")
    public void uploadPicture(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //这里就是把controller.jsp代码copy下来
        request.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "text/html");
        response.setHeader("X-Frame-Options", "SAMEORIGIN");// 解决IFrame拒绝的问题
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String configStr = new ActionEnter(request, rootPath).exec();
        response.getWriter().write(configStr);
    }

    @RequestMapping(value = "ue", method = RequestMethod.POST)
    public void ueUpload(HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException,
            FileUploadException {
        response.setHeader("X-Frame-Options", "SAMEORIGIN");// 解决IFrame拒绝的问题
        JSONObject jsonObject = new JSONObject();
        // 对上传文件夹和临时文件夹进行初始化
        String rootDir = loader.getProperty("user_defined_ui_graph_location");
        String tmpDir = rootDir + "/tmp";
        File tmpDirPath = new File(tmpDir);

        if (ServletFileUpload.isMultipartContent(request)) {
            request.setCharacterEncoding("utf-8");
            DiskFileItemFactory dff = new DiskFileItemFactory();// 创建该对象
            dff.setRepository(tmpDirPath);// 指定上传文件的临时目录
            dff.setSizeThreshold(2 * 1024 * 1024);// 指定在内存中缓存数据大小,单位为byte
            ServletFileUpload sfu = new ServletFileUpload(dff);// 创建该对象
            sfu.setFileSizeMax(1000000000);// 指定单个上传文件的最大尺寸
            sfu.setSizeMax(1000000000);// 指定一次上传多个文件的总尺寸
            List<FileItem> fiiList = sfu.parseRequest(request);// 解析request
            // 请求,并返回FileItemIterator集合
            for (int i = 0; i < fiiList.size(); i++) {
                FileItem fis = fiiList.get(i);// 从集合中获得一个文件流
                if (!fis.isFormField() && fis.getName().length() > 0) {// 过滤掉表单中非文件域
                    String filename = fis.getName();
                    String[] FileName = filename.split("\\.");
                    String preFile = FileName[0];
                    String endFile = FileName[1];
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                    String nowdate = sdf.format(date);
                    String newFileName = preFile + "_" + nowdate + "." + endFile;
                    File appDir = new File(rootDir);
                    if (!appDir.isDirectory()) {
                        appDir.mkdir();
                    }
                    // 创建按月分类的子文件夹
                    String currentMonth = DateUtils.formatDate(new Date(), "yyyyMM");
                    File appSubDir = new File(appDir + "/" + currentMonth);
                    if (!appSubDir.isDirectory()) {
                        appSubDir.mkdir();
                    }
                    String newFilepath = appSubDir + "/" + newFileName;
                    BufferedInputStream in = new BufferedInputStream(fis.getInputStream());// 获得文件输入流
                    BufferedOutputStream out =
                            new BufferedOutputStream(new FileOutputStream(new File(newFilepath)));// 获得文件输出流
                    Streams.copy(in, out, true);// 开始把文件写到你指定的上传文件夹
                    jsonObject.put("result_code", "SUCCESS");
                    jsonObject.put("result_value", "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/" + "dashboard" + "/" + currentMonth + "/" + newFileName + "/" + "get.do");
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter().write(jsonObject.toJSONString());
                }
            }
        }
    }

    @RequestMapping(value = "/{appPath}/{imageId}/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public void getRealDataImage(@PathVariable("appPath") String appPath, @PathVariable("imageId") String imageId,
                                 HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String serverSavePath = loader.getProperty("user_defined_ui_graph_location");
        String fileAbsolutePath = serverSavePath + System.getProperty("file.separator") + appPath + System.getProperty("file.separator") + imageId;
        String pictureType = imageId.split("\\.")[1];
        response.setContentType("image/x-png");
        response.setCharacterEncoding("UTF-8");
        File file = new File(fileAbsolutePath);
        BufferedImage image = ImageIO.read(file);
        ImageIO.write(image, pictureType, response.getOutputStream());
    }

	
}
